﻿/**
  ******************************************************************************
  * @file    Libraries/Device/JS32T031/JS32T031_LL_Driver/inc/js32t031_ll_eflash.h
  * @author  JUSHENG Application Team
  * @version V1.0.0
  * @date    02-19-2022
  * @brief   This file contains all the EFLASH LL firmware functions.
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2022 JUSHENG</center></h2>
  *
  *
  *
  ******************************************************************************
  */ 
  
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __JS32T031_LL_EFLASH_H
#define __JS32T031_LL_EFLASH_H

#ifdef __cplusplus
 extern "C" {
#endif

/* Includes ------------------------------------------------------------------*/
#include "js32t031.h"
     
/** @addtogroup JS32T031_StdPeriph_Driver JS32T031 Driver
  * @{
  */

/** @addtogroup eflash_interface_gr EFLASH Driver
  * @ingroup  JS32T031_StdPeriph_Driver
  * @{
  */ 

/** @addtogroup EFLASH_LL_Driver EFLASH LL Driver
  * @ingroup  eflash_interface_gr
  * @brief Mainly the driver part of the EFLASH module, which includes \b EFLASH \b Register 
  * \b Constants, \b EFLASH \b Exported \b Constants, \b EFLASH \b Exported \b Struct, \b EFLASH
  * \b Data \b transfers \b functions, \b EFLASH \b Initialization \b and \b EFLASH \b Configuration 
  * \b And \b Interrupt \b Handle \b function.
  * @{
  */

/* Exported types ------------------------------------------------------------*/

/* Exported constants --------------------------------------------------------*/

/** @defgroup EFLASH_LL_Register_Constants EFLASH LL Register Constants
  * @ingroup  EFLASH_LL_Driver
  * @brief    EFLASH LL register constant table definition
  *
  *
@verbatim   
  ===============================================================================
                                Register Constants
  ===============================================================================  
  
    Register Constants mainly encapsulates each bit in each group in the EFLASH 
    register. In the process of configuration, the macro definition can be directly 
    called to configure the EFLASH register, mainly for convenience. Understand the 
    configuration of the EFLASH.

@endverbatim
  *
  * @{
  */

/***** CTRLR0(Register) *****/
/*! eflash Program clock source selection, RC clock is recommended  
 * 0: high speed RC clock 2 frequency division  
 * 1: crystal vibration, use only if RC is not inaccuracy  
 */
#define LL_EF_CTRLR0_PROG_CLK_EXOSC_SEL                     (1UL << 16)

/*! The CRC value is added at the end when the RAM data is copied to EFLASH  
 * 0: disable  
 * 1: enable  
 */
#define LL_EF_CTRLR0_PROG_RAM_TO_EFLASH_ADD_CRC_EN          (1UL << 12)

/*! In case of LVD power failure, whether you can interrupt the eflash program and erase?  
 * In general, in case of power failure, you can immediately save important data on eflash  
 * and enable this function to quickly keep eflash idle  
 * 0: not allowed  
 * 1: allows  
 */
#define LL_EF_CTRLR0_LVD_PROG_STOP                          (1UL << 11)

/*! Write RAM data directly to eflash, and automatically add CRC check value at the end of eflash,  
 * specifically affecting several registers PROG_ADDR, CRC_ADDR, CRC_LEN  
 * 0: CRC mode  
 * 1: RAM to EFLASH mode  
 */
#define LL_EF_CTRLR0_AUTO_PROGRAM_MODE                      (1UL << 10)


/***** KST(Register) *****/
/*! CRC kick check start EN(wo)
 */
#define LL_EF_KST_CRC_KST_EN                                (1UL << 26)

/*! CRC Kick Start(wo), Write '1' trigger at the same time as the 26th bit digit  
 */
#define LL_EF_KST_CRC_KST                                   (1UL << 10)


/***** DONE(Register) *****/
/*! Chip erase ok flag(ro)  
 * 0: erase failure  
 * 1: erase success  
*/
#define LL_EF_DONE_CHIP_ERASE_OK                            (1UL << 12)

/*! Sector program ok flag(ro)  
 * 0: program failure  
 * 1: program success  
 */
#define LL_EF_DONE_PROG_OK                                  (1UL << 11)

/*! CRC done flag(ro)  
 * 0: doing  
 * 1: idle  
 */
#define LL_EF_DONE_CRC_DONE                                 (1UL << 10)

/*! Program finished done flag(ro)  
 * 0: doing  
 * 1: idle  
 */
#define LL_EF_DONE_PROG_DONE                                (1UL << 6)

/*! Chip Erase Done flag(ro)  
 * 0: doing  
 * 1: idle  
 */
#define LL_EF_DONE_CHIP_ERASE_DONE                          (1UL << 1)

/*! Sector(512byte) Erase Done flag(ro)  
 * 0: doing  
 * 1: idle  
 */
#define LL_EF_DONE_SECT_ERASE_DONE                          (1UL << 0)


/***** PROG_ADDR(Register) *****/
/*! Whether the programmed address is an NVR region  
 * 0: MAIN region  
 * 1: NVR region  
 */
#define LL_EF_PROG_ADDR_PROG_NVR_EN                         (1UL << 29)

/*! Eflash programming address, word as a unit for the program  
 * Note: when the tenth digit in the configuration register is valid.  
 * It serves as the starting address for eflash programming  
 */
#define LL_EF_PROG_ADDR_PROG_BYTE_ADDR(n)                   (((u32)(n) & 0xFFFF) << 0)


/***** PROG_DATA(Register) *****/
 /*! Eflash programming data, need to be configured to address  
 * Note: this register serves as eflash programmed data when the 10th digit in the configuration register is valid  
 */
#define LL_EF_PROG_DATA(n)                                  (((u32)(n) & 0xFFFFFFFF) << 0)


/***** ERASE_CTRL(Register) ******/
/*! Chip full erase trigger, write "1" trigger, you need to configure the password first(ro)  
 */
#define LL_EF_ERASE_CTRL_CHIP_ERASE_KICK_START              (1UL << 31)

/*! Sector erase trigger, write "1" trigger, need to configure the password first(ro)  
 */
#define LL_EF_ERASE_CTRL_SECTOR_ERASE_KICK_START            (1UL << 30)

/*! Nvr Sector select  
 * 0: MAIN  
 * 1: NVR  
 */
#define LL_EF_ERASE_CTRL_SECTOR_NVR_SEL                     (1UL << 29)

/*! Erase sector selection, range: 0-127  
 */
#define LL_EF_ERASE_CTRL_ERASE_SECTOR_ADDR(n)               (((u32)(n) & 0x7F) << 0)


/***** TIME_REG0(Register) ******/
/*! WEb low to PROG2 high hold min time is 500ns
 */ 
#define LL_EF_TIME_REG0_PGH(n)                              (((u32)(n) & 0x0F) << 16)

/*! BYTE/Address/data setup min time is 500ns
 */
#define LL_EF_TIME_REG0_ADS(n)                              (((u32)(n) & 0x0F) << 12)

/*! BYTE/Address/data hold min time 500 15ns
 */
#define LL_EF_TIME_REG0_ADH(n)                              (((u32)(n) & 0x0F) << 8)

/*! Latency to next operation after PROG/ERASE low min time is 500ns  
 */ 
#define LL_EF_TIME_REG0_RW(n)                               (((u32)(n) & 0x0F) << 4)

/*! Read Cycle Min Time is 30ns
 */   
#define LL_EF_TIME_REG0_RC(n)                               (((u32)(n) & 0x0F) << 0)


/***** TIME_REG1(Register) ******/
/*! 1ms time configuration value, in units of 1us,default: 1000.  
 */
#define LL_EF_TIME_REG1_MS(n)                               (((u32)(n) & 0x7FF) << 8)

/*! 1us time configuration value, flash ctl freq default: 24/2 MHz, the system default is 24MHz.  
 */ 
#define LL_EF_TIME_REG1_US(n)                               (((u32)(n) & 0xFF) << 0)


/***** NVR_PASSWORD(Register) ******/
/*! The NVR0~2 password is 0x20150931. Only after opening the password can the NVR be erased and programmed  
 */
#define LL_EF_NVR_PASSWORD(n)                               (((u32)(n) & 0xFFFFFFFF) << 0)


/***** MAIN_PASSWORD(Register) ******/
/*! The password is 0x20170230. Only after opening the password can the MAIN be erased and programmed  
 */
#define LL_EF_MAIN_PASSWORD(n)                              (((u32)(n) & 0xFFFFFFFF) << 0)


/***** CRC_ADDR(Register) ******/
/*! If the address is NVR region  
 * 0: MAIN region  
 * 1: NVR region  
 */
#define LL_EF_CRC_ADDR_NVR_EN                               (1UL << 29)

/*! byte address, phyic addr, Fix the lower 2-bit address to 0, word align.  
 * The starting address for CRC DMA, which points only to eflash, is the physical address.  
 * Note: when the tenth digit in the configuration register is valid, the register is configured as the address of RAM.  
 */
#define LL_EF_CRC_ADDR(n)                                   (((u32)(n) & 0x1FFFFFFC) << 0)

/***** CRC_LEN(Register) ******/
/*! Length of CRC DMA byte , Fix the lower 2-bit address to 0, word align  
 * Note: this register is configured as the length of RAM when the 10th digit in the configuration register is valid  
 */
#define LL_EF_CRC_DMA_LEN(n)                                (((u32)(n) & 0xFFFC) << 0)

/**
  * @}
  */

/** @defgroup EFLASH_LL_Exported_Constants EFLASH LL Exported Constants
  * @ingroup  EFLASH_LL_Driver
  * @brief    EFLASH LL external constant definition
  *
@verbatim   
  ===============================================================================
                                Exported Constants
  ===============================================================================  
  
    Exported Constants mainly restricts the partial configuration of the abstraction 
    layer by using the form of enumeration to facilitate the use and understanding of 
    the module configuration. For the specific enumeration meaning, please refer to 
    the annotation of each module.

@endverbatim
  *
  * @{
  */
  
/***** DRIVER API *****/
/*! eflash sector size 
 */
#define LL_EF_SECTOR_SIZE                                   512

/*! eflash main sector numbers 
 */
#define LL_EF_MAIN_SECTOR_NUM                               128

/*! eflash nvr sector numbers 
 */
#define LL_EF_NVR_SECTOR_NUM                                9

/*! eflash main and nvr sector numbers 
 */
#define LL_EF_MAIN_NVR_SECTOR_NUM                           (LL_EF_MAIN_SECTOR_NUM + LL_EF_NVR_SECTOR_NUM)

/*! eflash nvr base address in the alias region
 */
#define LL_EF_NVR_BASE                                      (0x1FF00000)

/*! eflash password for main 
 */
#define LL_EF_HW_MAIN_PASSWORD                              0x20170230

/*! eflash password for nvr 
 */
#define LL_EF_HW_NVR_PASSWORD                               0x20150931


/***** LL API *****/

/***** LL API AND DRIVER API *****/

/**
  * @brief EFLASH proramming lock or unlock
  */
typedef enum {
    /*! EFLASH proram unlock 
     */  
    LL_EF_UNLOCK = 0,
    /*! EFLASH proram lock 
     */  
    LL_EF_LOCK,
} TYPE_ENUM_LL_EF_LOCK;

/**
  * @brief EFLASH proramming clock selection
  */
typedef enum {
    /*! EFLASH proram clk : rc 2 divition 
     */
    LL_EF_PROG_CLK_RC2DIV    = 0,
    /*! EFLASH proram clk : exosc 
     */
    LL_EF_PROG_CLK_EXOSC     = 1,
} TYPE_ENUM_LL_EF_PROG_CLK_SEL;

/**
  * @}
  */

/** @defgroup EFLASH_LL_Exported_Struct EFLASH LL Exported Struct
  * @ingroup  EFLASH_LL_Driver
  * @brief    EFLASH LL external configuration structure definition
  *
@verbatim   
  ===============================================================================
                                Exported Struct
  ===============================================================================  

    Exported Struct mainly extracts the EFLASH registers from the API, and abstracts 
    the structure. As long as it implements the low coupling between the registers 
    and the registers, the user only needs to configure the structure of the abstraction 
    layer and call hal_eflash_init. Function, you can configure the EFLASH module without 
    involving the configuration of the collective register.

@endverbatim
  *
  * @{
  */

/**
  * @brief initialization structure for low layer EFLASH 
  */ 
typedef struct __ll_eflash_init {
    u8 reserved;
} TYPE_LL_EFLASH_INIT;


/**
  * @}
  */

/** @defgroup EFLASH_LL_Interrupt EFLASH LL Interrupt Handle function
  * @brief   EFLASH LL Interrupt Handle function
  *
@verbatim   
  ===============================================================================
                        Interrupt Handle function
  ===============================================================================  

    This subsection provides a set of functions allowing to manage the EFLASH  
    Interrupt Handle function.

    how to use?

    The EFLASH interrupt handler uses a callback method that reserves the interface 
    to the user in the form of a callback function. The client needs to initialize 
    the callback function when initializing the EFLASH in order for the interrupt to 
    be processed normally. 
   
@endverbatim
  *
  * @{
  */



/**
  * @}
  */
  
/** @defgroup EFLASH_LL_Inti_Cfg EFLASH LL Initialization And Configuration
  * @brief    EFLASH LL Initialization And Configuration
  *
@verbatim   
  ===============================================================================
                        Initialization And Configuration
  ===============================================================================  

    This subsection provides a set of functions allowing to manage the EFLASH data 
    Initialization and Configuration.
    
    how to use?

@endverbatim
  *
  * @{
  */

/**
  * @brief  ll_eflash_init
  * @param  p_eflash: Base address of eflash register
  * @param  p_init: TYPE_LL_EFLASH_INIT pointer to eflash init stuct
  * @retval None
  * @note   eflash clk : 26Mhz safty, but Need to be set to 8M on the FPGA
  */
void ll_eflash_init(EFLASH_TypeDef *p_eflash, TYPE_LL_EFLASH_INIT *p_init);

/**
  * @brief  ll_eflash_nvr_lock
  * @param  p_eflash: Base address of eflash register
  * @param  isLock: Whether to lock
  * @retval None
  */
void ll_eflash_nvr_lock(EFLASH_TypeDef *EFLASHx, TYPE_ENUM_LL_EF_LOCK isLock);
/**
  * @brief  ll_eflash_main_lock
  * @param  p_eflash: Base address of eflash register
  * @param  isLock: Whether to lock
  * @retval None
  */
void ll_eflash_main_lock(EFLASH_TypeDef *p_eflash, TYPE_ENUM_LL_EF_LOCK isLock);

/**
  * @brief  ll_eflash_timing_set
  * @param  p_eflash: Base address of eflash register
  * @param  time_reg0: timer register0
  * @param  time_reg1: timer register1
  * @retval None
  */
void ll_eflash_timing_set(EFLASH_TypeDef *p_eflash, u32 time_reg0, u32 time_reg1);

/**
  * @brief  ll_eflash_clk_sel_exosc
  * @param  p_eflash: Base address of eflash register
  * @retval None
  * @note osc clk : 26Mhz
  */
void ll_eflash_clk_sel(EFLASH_TypeDef *p_eflash, TYPE_ENUM_LL_EF_PROG_CLK_SEL exosc_sel);

/**
  * @brief  The CRC value is added at the end when the RAM data is copied to EFLASH enable
  * @param  p_eflash: Base address of eflash register
  * @retval None
  */
void ll_eflash_prog_ram_to_eflash_add_crc_enable(EFLASH_TypeDef *p_eflash);

/**
  * @brief  The CRC value is added at the end when the RAM data is copied to EFLASH disable
  * @param  p_eflash: Base address of eflash register
  * @retval None
  */
void ll_eflash_prog_ram_to_eflash_add_crc_disable(EFLASH_TypeDef *p_eflash);

/**
  * @brief  ll_eflash_cfg_sector_main_get
  * @param  p_eflash: Base address of eflash register
  * @retval cfg sector
  * @note   Sector location configured by the MAIN user
  */
u32 ll_eflash_cfg_sector_main_get(EFLASH_TypeDef *p_eflash);

/**
  * @}
  */
  
/** @defgroup EFLASH_LL_Data_Transfers EFLASH LL Data transfers functions
  * @brief    EFLASH LL Data transfers functions 
  *
@verbatim   
  ===============================================================================
                            Data transfers functions
  ===============================================================================  

    This subsection provides a set of functions allowing to manage the EFLASH data 
    transfers and receive.
  
@endverbatim
  *
  * @{
  */


/**
  * @brief  ll_eflash_prog_one_data_main
  * @param  p_eflash: Base address of eflash register
  * @param  addr: Write data address in eflash
  * @param  data: Write data to eflash
  * @retval None
  */
void ll_eflash_prog_one_data_main(EFLASH_TypeDef *p_eflash, u32 addr, u32 data);

/**
  * @brief  ll_eflash_prog_one_data_nvr
  * @param  p_eflash: Base address of eflash register
  * @param  addr: Write data address in eflash
  * @param  data: Write data to eflash
  * @retval None
  */
void ll_eflash_prog_one_data_nvr(EFLASH_TypeDef *p_eflash, u32 addr, u32 data);

/**
  * @brief  ll_eflash_prog_one_data include main and nvr
  * @param  p_eflash: Base address of eflash register
  * @param  addr: Write data address in eflash
  * @param  data: Write data to eflash
  * @retval None
  */
void ll_eflash_prog_one_data(EFLASH_TypeDef *p_eflash, u32 addr, u32 data);

/**
  * @brief  ll_eflash_erase_one_sector_main
  * @param  p_eflash: Base address of eflash register
  * @param  sect_num: The number of the sector in eflash
  * @retval None
  */
void ll_eflash_erase_one_sector_main(EFLASH_TypeDef *p_eflash, u16 sect_num);

/**
  * @brief  ll_eflash_erase_one_sector include main sector and nvr sector
  * @param  p_eflash: Base address of eflash register
  * @param  sect_num: The number of the sector in eflash
  * @retval None
  */
void ll_eflash_erase_one_sector(EFLASH_TypeDef *p_eflash, u16 sect_num);

/**
  * @brief  ll_eflash_erase_one_sector_NVR
  * @param  p_eflash: Base address of eflash register
  * @param  sect_num: The number of the sector in eflash
  * @retval None
  */
void ll_eflash_erase_one_sector_nvr(EFLASH_TypeDef *p_eflash, u16 sect_num);

/**
  * @brief  ll_eflash_erase_chip
  * @param  p_eflash: Base address of eflash register
  * @retval None
  */
void ll_eflash_erase_chip(EFLASH_TypeDef *p_eflash);

/**
  * @brief  ll_eflash_crc_calc
  * @param  p_eflash: Base address of eflash register
  * @param  st_address: phsic_addr, align: 4byte
  * @param  len :  align: 4byte  
  * @retval crc32 result
  */
u32 ll_eflash_crc32(EFLASH_TypeDef *p_eflash, u32 st_addr, u32 len);

/**
  * @brief  ll_eflash_auto_program
  * @param  p_eflash: Base address of eflash register
  * @param  ef_addr: eflash main physic_addr
  * @param  ram_addr: sram start address
  * @param  len
  * @retval None
  */
void ll_eflash_auto_program(EFLASH_TypeDef *p_eflash, u32 ef_addr, u32 ram_addr, u32 len);

/**
  * @brief  ll_eflash_auto_program_nvr
  * @param  p_eflash: Base address of eflash register
  * @param  ef_addr: eflash nvr physic_addr
  * @param  ram_addr: sram start address
  * @param  len
  * @retval None
  */
void ll_eflash_auto_program_nvr(EFLASH_TypeDef *p_eflash, u32 ef_addr, u32 ram_addr, u32 len);

/**
  * @brief  ll_eflash_crc_out_result_get
  * @param  p_eflash: Base address of eflash register
  * @retval crc result
  * @note   CRC results, polynomial crc-32 is as follows, the results out of the inverse is the official results  
            write EFLASH CRC need to take the official value of the inverse!!!  
            X32 + x26 + x23 + x22 + x16 + x12 + x11 + + by 8 x10 + + x 5 x7 + x4 + x2 + x + 1  
  */
u32 ll_eflash_crc_out_result_get(EFLASH_TypeDef *p_eflash);

/**
  * @brief  LL_EFLASH_DATA_GET
  * @param  addr: EFLASH hardware address(4 bytes align)
  * @retval value for eflash address content
  */
#define LL_EFLASH_DATA_GET(addr)                            (*((volatile u32 *)(addr)))

/**
  * @brief  LL_EFLASH_NVR_DATA_GET
  * @param  addr: EFLASH nvr hardware address(4 bytes align)
  * @retval value for eflash nvr address content
  */
#define LL_EFLASH_DATA_NVR_GET(addr)                        (*((volatile u32 *)(LL_EF_NVR_BASE + (addr))))

/**
  * @}
  */

/**
  * @}
  */

#ifdef __cplusplus
}
#endif

/**
  * @}
  */

/**
  * @}
  */

#endif //__JS32T031_LL_EFLASH_H

/*************************** (C) COPYRIGHT 2022 JUSHENG ***** END OF FILE *****/
